﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.ModularFixture.CApMFFixtureDesignerApplication
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using EMPMODELLib;
using EMPTYPELIBRARYLib;
using EngineeringInternalExtension;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Resources;
using System.Windows.Forms;
using Tecnomatix.Engineering;
using Tecnomatix.Planning;


namespace DnProcessSimulateCommands.ModularFixture;

internal class CApMFFixtureDesignerApplication
{
  internal const string OR_OPERATOR = "OR";
  internal const string AND_OPERATOR = "AND";
  private readonly int m_sessionId;
  private const double EPSILON = 0.0001;
  private const int MAX_SIZE = 1000;
  private const double MAX_DISTANCE = 1.7976931348623157E+308;
  private double m_minToleranceX;
  private double m_maxToleranceX;
  private double m_minToleranceY;
  private double m_maxToleranceY;
  private double m_minToleranceZ;
  private double m_maxToleranceZ;
  private int m_fixtureUnitId;
  private int m_fixtureBaseId;
  private CApMFTransformation m_fixtureUnitLocation;
  private TxTransformation m_fixtureBaseLocation;
  private TxFrame m_frame;
  private Hashtable m_previousVariations;
  private Hashtable m_intermediateVariations;
  private Hashtable m_intermediateVariationsLocations;
  private Hashtable m_instancesLocations;
  private Hashtable m_instancesPrototypes;
  private Hashtable m_prototypeChildren;
  private Hashtable m_raiserInternalIds;
  private Hashtable m_derivedInstances;
  private Hashtable m_resourcePlacementOrigin;
  private Hashtable m_toolPrototypesInVariationsHash;
  private CApMFFixtureDesignerEmsHandler m_emsHandler;
  private double m_angularMultiplier;
  private int m_angularDigitsAfterThePoint;
  private Hashtable m_internalIdsPlanningObjects;
  private bool m_shouldCollectPlacementOrigins;
  private ArrayList m_searchConditionsContainedInSolution;
  private ArrayList m_searchConditionsNotContainedInSolution;
  private ArrayList m_toolPrototypesInVariations;
  private ArrayList m_toolsWithoutVariations;
  private ArrayList m_placementOriginsWithoutVariations;
  private string m_solutionContainsOperator;
  private string m_solutionDoesntContainOperator;

  internal CApMFFixtureDesignerApplication()
  {
    this.m_previousVariations = new Hashtable();
    this.m_intermediateVariations = new Hashtable();
    this.m_emsHandler = new CApMFFixtureDesignerEmsHandler();
    this.m_intermediateVariationsLocations = new Hashtable();
    this.m_instancesLocations = new Hashtable();
    this.m_instancesPrototypes = new Hashtable();
    this.m_prototypeChildren = new Hashtable();
    this.m_raiserInternalIds = new Hashtable();
    this.m_derivedInstances = new Hashtable();
    this.m_resourcePlacementOrigin = new Hashtable();
    this.m_internalIdsPlanningObjects = new Hashtable();
    this.m_searchConditionsContainedInSolution = new ArrayList();
    this.m_searchConditionsNotContainedInSolution = new ArrayList();
    this.m_toolPrototypesInVariations = new ArrayList();
    this.m_toolPrototypesInVariationsHash = new Hashtable();
    this.m_toolsWithoutVariations = new ArrayList();
    this.m_angularMultiplier = TxApplication.Options.Units.AngularMultiplier;
    this.m_angularDigitsAfterThePoint = TxApplication.Options.Units.AngularDigitsAfterDecimalPoint;
    this.m_sessionId = TxApplication.ActiveDocument.eMSSessionId;
    this.m_solutionContainsOperator = "OR";
    this.m_solutionDoesntContainOperator = "OR";
  }

  internal TxCompoundResource CreateConfigurationInStudy(
    TxPlanningObject configurationPlanningObj,
    TxCompoundResource targetResource,
    TxTransformation location,
    bool isBase)
  {
    TxCompoundResource configurationRoot = this.CreateCompoundResourceForConfigurationRoot(configurationPlanningObj, targetResource, location);
    TxStringAttribute txStringAttribute = new TxStringAttribute("ConfigurationPrototypeId", configurationPlanningObj.ProcessModelId.ExternalId);
    ((TxAttribute) txStringAttribute).ShouldBeCopiedAsInstanceAttribute = true;
    configurationRoot.SetAttribute((TxAttribute) txStringAttribute);
    this.CreateConfigurationDescendantsInStudy(configurationRoot, configurationPlanningObj, targetResource, isBase);
    return configurationRoot;
  }

  internal void CreateConfigurationDescendantsInStudy(
    TxCompoundResource root,
    TxPlanningObject configurationPlanningObj,
    TxCompoundResource targetResource,
    bool isBase)
  {
    foreach (ITxPlanningObject instanceObj in (Collection<ITxObject>) configurationPlanningObj.GetField("children"))
      this.CreateConfigurationDescendants(instanceObj, (ITxCompoundResourceCreation) root, false, isBase, root.AbsoluteLocation);
    if (!TxCompoundResource.op_Inequality(root, (ITxObject) null))
      return;
    ((ITxDisplayableObject) root).Display();
  }

  internal ArrayList CalculatePossibleSolutions(
    int fixtureUnitProtoId,
    int fixtureBaseProtoId,
    TxTransformation fixtureUnitLocation,
    TxTransformation fixtureBaseLocation,
    ref bool areValidSolutions)
  {
    this.m_fixtureUnitId = fixtureUnitProtoId;
    this.m_fixtureBaseId = fixtureBaseProtoId;
    TxVector translation = fixtureUnitLocation.Translation;
    TxVector rotationRpyXyz = fixtureUnitLocation.RotationRPY_XYZ;
    this.m_fixtureUnitLocation = new CApMFTransformation(translation.X, translation.Y, translation.Z, rotationRpyXyz.X, rotationRpyXyz.Y, rotationRpyXyz.Z);
    this.m_fixtureBaseLocation = fixtureBaseLocation;
    ArrayList fromConfiguration = CApMFFixtureDesignerUtils.GetRaisersFromConfiguration(fixtureUnitProtoId);
    TxEmsGlobalServicesProvider servicesProvider = TxApplication.ActiveDocument.PlatformGlobalServicesProvider as TxEmsGlobalServicesProvider;
    TxPlanningObject objectByInternalId = servicesProvider.GetObjectByInternalId(fixtureUnitProtoId) as TxPlanningObject;
    ArrayList placementOriginPath = new ArrayList();
    this.m_placementOriginsWithoutVariations = !CApMFFixtureDesignerUtils.GetPlacementOriginFromConfiguration(objectByInternalId, ref placementOriginPath) ? new ArrayList() : placementOriginPath;
    CApMFFixtureDesignerUtils.GetToolPrototypesFromConfiguration(objectByInternalId, ref this.m_toolsWithoutVariations);
    if (this.m_searchConditionsContainedInSolution.Count > 0 || this.m_searchConditionsNotContainedInSolution.Count > 0)
      this.m_emsHandler.ImportDataToCacheForSearchConditions(fixtureUnitProtoId, this.m_searchConditionsContainedInSolution, this.m_searchConditionsNotContainedInSolution);
    ArrayList variations;
    if (this.m_previousVariations.Contains((object) fixtureUnitProtoId))
    {
      variations = (ArrayList) this.m_previousVariations[(object) fixtureUnitProtoId];
      this.m_toolPrototypesInVariations = (ArrayList) this.m_toolPrototypesInVariationsHash[(object) fixtureUnitProtoId];
    }
    else
    {
      EmpContext empContext;
      empContext.sessionId = this.m_sessionId;
      EmpObjectKey empObjectKey1;
      empObjectKey1.objectId = fixtureUnitProtoId;
      EmpObjectKey[] children = new EmpToolPrototypeClass().GetChildren(ref empContext, ref empObjectKey1);
      ArrayList resourcePath = new ArrayList();
      variations = new ArrayList();
      Hashtable variationHash = new Hashtable();
      foreach (EmpObjectKey empObjectKey2 in children)
        this.CaluclateAllPossibleVariations(servicesProvider.GetObjectByInternalId(empObjectKey2.objectId), ref variations, 0, resourcePath, true, variationHash);
      this.RemoveVariationsWithNoRaiser(ref variations, ref fromConfiguration);
      this.m_previousVariations.Add((object) fixtureUnitProtoId, (object) variations);
      this.m_toolPrototypesInVariationsHash.Add((object) fixtureUnitProtoId, (object) this.m_toolPrototypesInVariations);
    }
    CApMFFixtureDesignerUtils.GetToleranceForConfiguration(fixtureUnitProtoId, out this.m_minToleranceX, out this.m_maxToleranceX, out this.m_minToleranceY, out this.m_maxToleranceY, out this.m_minToleranceZ, out this.m_maxToleranceZ);
    ArrayList distancesForVariations = this.CalculateDistancesForVariations(ref variations, ref fromConfiguration, ref areValidSolutions);
    this.SortDistances(ref distancesForVariations);
    IDictionaryEnumerator enumerator = this.m_internalIdsPlanningObjects.GetEnumerator();
    while (enumerator.MoveNext())
      TxPlanningObjectEx.SetEmsServicesProviderCacheFlags(enumerator.Value as TxPlanningObject, (TxEmsServicesProviderCacheFlagsEx) 1);
    this.m_internalIdsPlanningObjects.Clear();
    this.m_intermediateVariations.Clear();
    this.m_intermediateVariationsLocations.Clear();
    this.m_placementOriginsWithoutVariations.Clear();
    this.m_toolsWithoutVariations.Clear();
    return distancesForVariations;
  }

  internal void CreateFullFixtureStructure(
    int configId,
    TxCompoundResource fixtureUnitCompRes,
    ref CApMFFixtureDesignerSolution solution)
  {
    EmpContext empContext;
    empContext.sessionId = this.m_sessionId;
    ITxTypeFilter itxTypeFilter = (ITxTypeFilter) new TxNoTypeFilter();
    foreach (ITxObject directDescendant in (Collection<ITxObject>) fixtureUnitCompRes.GetDirectDescendants(itxTypeFilter))
      directDescendant.Delete();
    EmpToolPrototypeClass toolPrototypeClass = new EmpToolPrototypeClass();
    EmpObjectKey empObjectKey;
    empObjectKey.objectId = configId;
    foreach (EmpObjectKey child in toolPrototypeClass.GetChildren(ref empContext, ref empObjectKey))
      this.CreateFixtureDescendatns(child.objectId, (ITxCompoundResourceCreation) fixtureUnitCompRes, ref solution, fixtureUnitCompRes.AbsoluteLocation);
  }

  internal void PlaceFixtureUnit(
    ref TxCompoundResource fixtureUnitCompRes,
    CApMFFixtureDesignerSolution solution)
  {
    TxVector translation = solution.PlacementPoint.Translation;
    TxVector rotationRpyXyz = solution.PlacementPoint.RotationRPY_XYZ;
    double num1;
    double num2;
    double num3;
    double num4;
    double num5;
    double num6;
    if (solution.IntermediateId == 0)
    {
      TxTransformation txTransformation1;
      if (this.m_resourcePlacementOrigin.Contains((object) solution.RaiserId))
      {
        CApMFTransformation mfTransformation = this.m_resourcePlacementOrigin[(object) solution.RaiserId] as CApMFTransformation;
        double x;
        double y;
        double z;
        mfTransformation.GetTranslation(out x, out y, out z);
        double rx;
        double ry;
        double rz;
        mfTransformation.GetRotationRPY(out rx, out ry, out rz);
        TxTransformation txTransformation2 = new TxTransformation(new TxVector(x, y, z), new TxVector(rx, ry, rz), (TxTransformation.TxRotationType) 1);
        txTransformation1 = TxTransformation.op_Multiply(solution.RaiserLocation, txTransformation2);
      }
      else
        txTransformation1 = solution.RaiserLocation;
      num1 = translation.X - txTransformation1.Translation.X;
      num2 = translation.Y - txTransformation1.Translation.Y;
      num3 = translation.Z - txTransformation1.Translation.Z;
      num4 = rotationRpyXyz.X - txTransformation1.RotationRPY_XYZ.X;
      num5 = rotationRpyXyz.Y - txTransformation1.RotationRPY_XYZ.Y;
      num6 = rotationRpyXyz.Z - txTransformation1.RotationRPY_XYZ.Z;
    }
    else
    {
      num1 = translation.X - solution.IntermediateLocation.Translation.X;
      num2 = translation.Y - solution.IntermediateLocation.Translation.Y;
      num3 = translation.Z - solution.IntermediateLocation.Translation.Z;
      num4 = rotationRpyXyz.X - solution.IntermediateLocation.RotationRPY_XYZ.X;
      num5 = rotationRpyXyz.Y - solution.IntermediateLocation.RotationRPY_XYZ.Y;
      num6 = rotationRpyXyz.Z - solution.IntermediateLocation.RotationRPY_XYZ.Z;
    }
    TxTransformation absoluteLocation = fixtureUnitCompRes.AbsoluteLocation;
    TxVector txVector1 = new TxVector(absoluteLocation.Translation.X + num1, absoluteLocation.Translation.Y + num2, absoluteLocation.Translation.Z + num3);
    TxVector txVector2 = new TxVector(absoluteLocation.RotationRPY_XYZ.X + num4, absoluteLocation.RotationRPY_XYZ.Y + num5, absoluteLocation.RotationRPY_XYZ.Z + num6);
    fixtureUnitCompRes.AbsoluteLocation = new TxTransformation(txVector1, txVector2, (TxTransformation.TxRotationType) 1);
  }

  internal bool IsConfigurationType(ITxPlanningObject planningObj)
  {
    bool flag = false;
    EmpContext empContext;
    empContext.sessionId = this.m_sessionId;
    TxEmsServicesProvider servicesProvider = planningObj.PlatformServicesProvider as TxEmsServicesProvider;
    EmpFieldInfo field = ((IEmpObject) new EmpObjectClass()).GetField(ref empContext, ref new EmpObjectKey()
    {
      objectId = servicesProvider.InternalId
    }, "ConfigurationType");
    if (field.Value != null && ((string) field.Value).Equals("Configuration"))
      flag = true;
    return flag;
  }

  internal bool IsConfigurationType(int internalId)
  {
    bool flag = false;
    EmpContext empContext;
    empContext.sessionId = this.m_sessionId;
    EmpFieldInfo field = ((IEmpObject) new EmpObjectClass()).GetField(ref empContext, ref new EmpObjectKey()
    {
      objectId = internalId
    }, "ConfigurationType");
    if (field.Value != null && ((string) field.Value).Equals("Configuration"))
      flag = true;
    return flag;
  }

  internal bool IsFixtureBaseType(ITxPlanningObject planningObj)
  {
    bool flag = false;
    EmpContext empContext;
    empContext.sessionId = this.m_sessionId;
    TxEmsServicesProvider servicesProvider = planningObj.PlatformServicesProvider as TxEmsServicesProvider;
    EmpFieldInfo field = ((IEmpObject) new EmpObjectClass()).GetField(ref empContext, ref new EmpObjectKey()
    {
      objectId = servicesProvider.InternalId
    }, "ConfigurationType");
    if (field.Value != null && ((string) field.Value).Equals("FixtureBase"))
      flag = true;
    return flag;
  }

  internal void CreateFrameInGraphicViewer(TxTransformation transformation)
  {
    this.DeleteFrame();
    this.m_frame = TxFrameEx.CreateFrame(new TxFrameCreationDataEx("workingFrameTemp", transformation, true));
    TxApplication.RefreshDisplay();
  }

  internal void DeleteFrame()
  {
    if (!TxFrame.op_Inequality(this.m_frame, (ITxObject) null))
      return;
    this.m_frame.Delete();
    this.m_frame = (TxFrame) null;
    TxApplication.RefreshDisplay();
  }

  internal void SetConditions(
    ref ArrayList searchConditionsContained,
    ref ArrayList searchConditionsNotContained,
    string solutionContainsOperator,
    string solutionDoesntContainOperator)
  {
    this.m_searchConditionsContainedInSolution = searchConditionsContained;
    this.m_searchConditionsNotContainedInSolution = searchConditionsNotContained;
    this.m_solutionContainsOperator = solutionContainsOperator;
    this.m_solutionDoesntContainOperator = solutionDoesntContainOperator;
  }

  internal void CaluclateAllPossibleVariations(
    ITxPlanningObject instancePlanningObj,
    ref ArrayList variations,
    int varParentId,
    ArrayList resourcePath,
    bool isRaiser,
    Hashtable variationHash)
  {
    int idFromPlanningObj1 = this.GetInternalIdFromPlanningObj((TxPlanningObject) instancePlanningObj);
    ITxPlanningObject planningObjectFromHash1 = this.GetPlanningObjectFromHash(idFromPlanningObj1, "prototype", ref this.m_instancesPrototypes, instancePlanningObj);
    CApMFFixtureDesignerApplication.ClassType classType;
    if (this.m_derivedInstances.Contains((object) idFromPlanningObj1))
    {
      classType = (CApMFFixtureDesignerApplication.ClassType) this.m_derivedInstances[(object) idFromPlanningObj1];
    }
    else
    {
      classType = !planningObjectFromHash1.IsDerivedFromPlanningType("UnitConfigurationVarPrototype") ? (!planningObjectFromHash1.IsDerivedFromPlanningType("UnitConfigurationPrototype") ? CApMFFixtureDesignerApplication.ClassType.TOOL_PROTOTYPE : CApMFFixtureDesignerApplication.ClassType.CONFIGURATION) : CApMFFixtureDesignerApplication.ClassType.VARIATION;
      this.m_derivedInstances.Add((object) idFromPlanningObj1, (object) classType);
    }
    switch (classType)
    {
      case CApMFFixtureDesignerApplication.ClassType.CONFIGURATION:
        resourcePath.Add((object) idFromPlanningObj1);
        foreach (ITxPlanningObject instancePlanningObj1 in (Collection<ITxObject>) this.GetObjectListFromHash(this.GetInternalIdFromPlanningObj((TxPlanningObject) planningObjectFromHash1), "children", ref this.m_prototypeChildren, planningObjectFromHash1))
          this.CaluclateAllPossibleVariations(instancePlanningObj1, ref variations, varParentId, resourcePath, isRaiser, variationHash);
        resourcePath.RemoveAt(resourcePath.Count - 1);
        break;
      case CApMFFixtureDesignerApplication.ClassType.VARIATION:
        TxObjectList objectListFromHash = this.GetObjectListFromHash(this.GetInternalIdFromPlanningObj((TxPlanningObject) planningObjectFromHash1), "children", ref this.m_prototypeChildren, planningObjectFromHash1);
        this.HandleVariationPrototype(varParentId, ref variations, ref variationHash, ref objectListFromHash, isRaiser);
        using (IEnumerator<ITxObject> enumerator = ((Collection<ITxObject>) objectListFromHash).GetEnumerator())
        {
          while (enumerator.MoveNext())
          {
            ITxPlanningObject current = (ITxPlanningObject) enumerator.Current;
            int idFromPlanningObj2 = this.GetInternalIdFromPlanningObj((TxPlanningObject) current);
            ITxPlanningObject planningObjectFromHash2 = this.GetPlanningObjectFromHash(idFromPlanningObj2, "prototype", ref this.m_instancesPrototypes, current);
            foreach (ITxPlanningObject instancePlanningObj2 in (Collection<ITxObject>) this.GetObjectListFromHash(this.GetInternalIdFromPlanningObj((TxPlanningObject) planningObjectFromHash2), "children", ref this.m_prototypeChildren, planningObjectFromHash2))
              this.CaluclateAllPossibleVariations(instancePlanningObj2, ref variations, idFromPlanningObj2, resourcePath, isRaiser, variationHash);
          }
          break;
        }
      default:
        bool flag1 = false;
        if (isRaiser)
        {
          CApMFTransformation placementOrigin = (CApMFTransformation) null;
          if (!this.m_resourcePlacementOrigin.Contains((object) idFromPlanningObj1))
          {
            flag1 = CApMFFixtureDesignerUtils.GetPlacementOrigin(idFromPlanningObj1, ref placementOrigin);
            if (flag1)
              this.m_resourcePlacementOrigin.Add((object) idFromPlanningObj1, (object) placementOrigin);
          }
          else
            flag1 = true;
        }
        if (varParentId == 0 || !variationHash.Contains((object) varParentId))
          break;
        bool flag2 = flag1 || this.CheckIfRaiserOrIntermediate(isRaiser, instancePlanningObj, idFromPlanningObj1, planningObjectFromHash1) && variationHash.Count > 0;
        ArrayList arrayList1 = variationHash[(object) varParentId] as ArrayList;
        int idFromPlanningObj3 = this.GetInternalIdFromPlanningObj((TxPlanningObject) planningObjectFromHash1);
        IEnumerator enumerator1 = arrayList1.GetEnumerator();
        try
        {
          while (enumerator1.MoveNext())
          {
            int current = (int) enumerator1.Current;
            if (isRaiser && !(this.m_toolPrototypesInVariations[current] as ArrayList).Contains((object) idFromPlanningObj3))
              ((ArrayList) this.m_toolPrototypesInVariations[current]).Add((object) idFromPlanningObj3);
            if (flag2)
            {
              ArrayList arrayList2 = (ArrayList) resourcePath.Clone();
              arrayList2.Add((object) idFromPlanningObj1);
              if (this.ShouldCollectPlacementOrigins)
              {
                if (flag1)
                {
                  if (!(((ArrayList) variations[current])[0] is ArrayList))
                    ((ArrayList) variations[current]).Insert(0, (object) new ArrayList());
                  if (!((ArrayList) ((ArrayList) variations[current])[0]).Contains((object) idFromPlanningObj3))
                    ((ArrayList) ((ArrayList) variations[current])[0]).Add((object) idFromPlanningObj3);
                }
              }
              else
              {
                object obj = ((ArrayList) variations[current])[0];
                if (flag1 && obj is ArrayList)
                {
                  ArrayList arrayList3 = ((ArrayList) variations[current])[0] as ArrayList;
                  if (!this.m_resourcePlacementOrigin.Contains(arrayList3[arrayList3.Count - 1]))
                    ((ArrayList) variations[current]).RemoveAt(0);
                }
                if (!(((ArrayList) variations[current])[0] is ArrayList))
                {
                  ((ArrayList) variations[current]).Insert(0, (object) arrayList2);
                  if (!isRaiser)
                  {
                    CApMFTransformation mfTransformation = CApMFFixtureDesignerUtils.GetIntermediatePlacementPoint(idFromPlanningObj1).Inverse();
                    ((ArrayList) variations[current]).Insert(1, (object) mfTransformation);
                  }
                }
              }
            }
          }
          break;
        }
        finally
        {
          if (enumerator1 is IDisposable disposable)
            disposable.Dispose();
        }
    }
  }

  private TxCompoundResource CreateCompoundResourceForConfigurationRoot(
    TxPlanningObject configurationPlanningObj,
    TxCompoundResource targetResource,
    TxTransformation location)
  {
    EmpContext empContext;
    empContext.sessionId = this.m_sessionId;
    TxEmsServicesProvider servicesProvider = configurationPlanningObj.PlatformServicesProvider as TxEmsServicesProvider;
    TxCompoundResourceCreationData resourceCreationData = new TxCompoundResourceCreationData();
    ((TxObjectCreationData) resourceCreationData).Name = this.GetUniqueResourceName(TxObjectEx.GetPlanningObjectName((ITxObject) configurationPlanningObj), targetResource);
    TxCompoundResource compoundResource = targetResource.CreateCompoundResource(resourceCreationData);
    compoundResource.AbsoluteLocation = location;
    return compoundResource;
  }

  private string GetUniqueResourceName(string resourceName, TxCompoundResource targetResource)
  {
    string str = resourceName;
    TxTypeFilter txTypeFilter = new TxTypeFilter(typeof (TxCompoundResource));
    TxObjectList allDescendants = targetResource.GetAllDescendants((ITxTypeFilter) txTypeFilter);
    bool flag = true;
    for (int index = 1; index < 1000 & flag; ++index)
    {
      flag = false;
      foreach (TxCompoundResource compoundResource in (Collection<ITxObject>) allDescendants)
      {
        if (compoundResource.Name.Equals(resourceName))
          flag = true;
      }
      if (flag)
        resourceName = $"{str}_{index.ToString()}";
    }
    return resourceName;
  }

  private void CreateConfigurationDescendants(
    ITxPlanningObject instanceObj,
    ITxCompoundResourceCreation compoundRes,
    bool forceCreate,
    bool isBase,
    TxTransformation currentLocation)
  {
    EmpContext empContext;
    empContext.sessionId = this.m_sessionId;
    EmpToolPrototypeClass toolPrototypeClass = new EmpToolPrototypeClass();
    int idFromPlanningObj1 = this.GetInternalIdFromPlanningObj((TxPlanningObject) instanceObj);
    ITxPlanningObject planningObjectFromHash = this.GetPlanningObjectFromHash(idFromPlanningObj1, "prototype", ref this.m_instancesPrototypes, instanceObj);
    int idFromPlanningObj2 = this.GetInternalIdFromPlanningObj((TxPlanningObject) planningObjectFromHash);
    EmpObjectKey empObjectKey;
    empObjectKey.objectId = idFromPlanningObj2;
    bool flag = planningObjectFromHash.IsDerivedFromPlanningType("UnitConfigurationVarPrototype");
    if (flag && !this.m_derivedInstances.Contains((object) idFromPlanningObj1))
      this.m_derivedInstances.Add((object) idFromPlanningObj1, (object) CApMFFixtureDesignerApplication.ClassType.VARIATION);
    ITxPlanningObject field1 = (ITxPlanningObject) instanceObj.GetField("layout");
    if (!(Convert.ToInt32(instanceObj.GetField("BasicUnitStructure")) == 1 | flag | forceCreate | isBase))
      return;
    forceCreate = false;
    ArrayList field2 = (ArrayList) field1.GetField("location");
    ArrayList field3 = (ArrayList) field1.GetField("rotation");
    TxTransformation txTransformation = new TxTransformation(new TxVector(Convert.ToDouble(field2[0]), Convert.ToDouble(field2[1]), Convert.ToDouble(field2[2])), new TxVector(Convert.ToDouble(field3[0]), Convert.ToDouble(field3[1]), Convert.ToDouble(field3[2])), (TxTransformation.TxRotationType) 1);
    TxTransformation currentLocation1 = TxTransformation.op_Multiply(currentLocation, txTransformation);
    if (planningObjectFromHash.IsDerivedFromPlanningType("UnitConfigurationPrototype"))
    {
      if (!this.m_derivedInstances.Contains((object) idFromPlanningObj1))
        this.m_derivedInstances.Add((object) idFromPlanningObj1, (object) CApMFFixtureDesignerApplication.ClassType.CONFIGURATION);
      TxCompoundResourceCreationData resourceCreationData = new TxCompoundResourceCreationData(TxObjectEx.GetPlanningObjectName((ITxObject) instanceObj), currentLocation1);
      TxCompoundResource compoundResource = compoundRes.CreateCompoundResource(resourceCreationData);
      foreach (ITxPlanningObject instanceObj1 in (Collection<ITxObject>) this.GetObjectListFromHash(idFromPlanningObj2, "children", ref this.m_prototypeChildren, planningObjectFromHash))
        this.CreateConfigurationDescendants(instanceObj1, (ITxCompoundResourceCreation) compoundResource, forceCreate, isBase, currentLocation1);
    }
    else if (flag)
    {
      this.CreateConfigurationDescendants((ITxPlanningObject) ((Collection<ITxObject>) planningObjectFromHash.GetField("children"))[0], compoundRes, true, isBase, currentLocation1);
    }
    else
    {
      if (!planningObjectFromHash.IsDerivedFromPlanningType("ToolPrototype"))
        return;
      if (!this.m_derivedInstances.Contains((object) idFromPlanningObj1))
        this.m_derivedInstances.Add((object) idFromPlanningObj1, (object) CApMFFixtureDesignerApplication.ClassType.TOOL_PROTOTYPE);
      EmpObjectKey threeDrep = toolPrototypeClass.GetThreeDRep(ref empContext, ref empObjectKey);
      string str = new EmpThreeDRepClass()[ref empContext, ref threeDrep];
      ITxComponent itxComponent = TxApplication.ActiveDocument.PhysicalRoot.InsertComponent(new TxInsertComponentCreationData(TxObjectEx.GetPlanningObjectName((ITxObject) instanceObj), str)
      {
        Prototype = planningObjectFromHash
      });
      ITxObjectCollection objectCollection = compoundRes as ITxObjectCollection;
      if (objectCollection.CanBeAdded((ITxObject) itxComponent))
        objectCollection.AddObject((ITxObject) itxComponent);
      (itxComponent as ITxLocatableObject).AbsoluteLocation = currentLocation1;
    }
  }

  private bool IsUnit(int internalId)
  {
    bool flag = false;
    EmpContext empContext;
    empContext.sessionId = this.m_sessionId;
    if (((string) ((IEmpObject) new EmpObjectClass()).GetField(ref empContext, ref new EmpObjectKey()
    {
      objectId = internalId
    }, "ConfigurationType").Value).Equals("Unit"))
      flag = true;
    return flag;
  }

  private void SortDistances(ref ArrayList solutions)
  {
    CApFixtureCompareTwoSolutions compareTwoSolutions = new CApFixtureCompareTwoSolutions();
    solutions.Sort((IComparer) compareTwoSolutions);
  }

  private void RemoveVariationsWithNoRaiser(ref ArrayList variations, ref ArrayList raisers)
  {
    for (int index = 0; index < variations.Count; ++index)
    {
      if (!(((ArrayList) variations[index])[0] is ArrayList))
      {
        if (raisers.Count == 0)
        {
          variations.RemoveAt(index);
          --index;
        }
        else
        {
          ArrayList arrayList = (ArrayList) ((ArrayList) raisers[0]).Clone();
          ((ArrayList) variations[index]).Insert(0, (object) arrayList);
        }
      }
    }
  }

  private void RemoveIntermediateVariationsWithNoFrame(ref ArrayList variations)
  {
    for (int index = 0; index < variations.Count; ++index)
    {
      if (!(((ArrayList) variations[index])[0] is ArrayList))
      {
        variations.RemoveAt(index);
        --index;
      }
    }
  }

  private ArrayList CalculateDistancesForVariations(
    ref ArrayList variations,
    ref ArrayList raisersWithoutVar,
    ref bool areValidSolutions)
  {
    ArrayList validSolutions = new ArrayList();
    ArrayList invalidSolutions = new ArrayList();
    ArrayList placementPoints = CApMFFixtureDesignerUtils.GetPlacementPoints(this.m_fixtureBaseId);
    this.AdjustPlacementPoints(ref placementPoints);
    if (variations.Count > 0)
    {
      for (int index = 0; index < variations.Count; ++index)
      {
        if (this.DoesVariationSatisfyConditions(index))
        {
          CApMFFixtureDesignerSolution solution = new CApMFFixtureDesignerSolution();
          ArrayList raiserPath = (ArrayList) ((ArrayList) variations[index])[0];
          ArrayList arrayList = ((ArrayList) variations[index]).Clone() as ArrayList;
          solution.VariationPath = arrayList;
          this.GetDistanceForVariation(ref raiserPath, ref validSolutions, ref invalidSolutions, ref solution, ref placementPoints, index);
        }
      }
    }
    else if (raisersWithoutVar.Count > 0)
    {
      ArrayList raiserPath = (ArrayList) raisersWithoutVar[0];
      if (raisersWithoutVar.Count > 1)
      {
        ResourceManager resourceManager = new ResourceManager("DnProcessSimulateCommands.ModularFixture.FixtureDesigner.Res.StringTable", this.GetType().Assembly);
        EmpContext empContext;
        empContext.sessionId = this.m_sessionId;
        EmpObjectKey empObjectKey;
        empObjectKey.objectId = (int) raiserPath[raiserPath.Count - 1];
        string str = new EmpToolInstanceClass()[ref empContext, ref empObjectKey];
        int num = (int) TxMessageBox.Show(resourceManager.GetString("MORE_THAN_ONE_RAISER_MESSAGE") + str, resourceManager.GetString("DESIGNER_APPLICATION_CMD_NAME"), MessageBoxButtons.OK, MessageBoxIcon.Hand);
      }
      CApMFFixtureDesignerSolution solution = new CApMFFixtureDesignerSolution();
      this.GetDistanceForVariation(ref raiserPath, ref validSolutions, ref invalidSolutions, ref solution, ref placementPoints, -1);
    }
    else
    {
      ResourceManager resourceManager = new ResourceManager("DnProcessSimulateCommands.ModularFixture.FixtureDesigner.Res.StringTable", this.GetType().Assembly);
      if (raisersWithoutVar.Count == 0)
      {
        int num = (int) TxMessageBox.Show(resourceManager.GetString("NO_RAISER_ERROR_MESSAGE"), resourceManager.GetString("DESIGNER_APPLICATION_CMD_NAME"), MessageBoxButtons.OK, MessageBoxIcon.Hand);
        return validSolutions;
      }
    }
    if (validSolutions.Count > 0)
    {
      areValidSolutions = true;
      return validSolutions;
    }
    areValidSolutions = false;
    return invalidSolutions;
  }

  private bool DoesVariationSatisfyConditions(int index)
  {
    bool flag1 = false;
    bool flag2 = false;
    bool flag3;
    if (this.m_searchConditionsContainedInSolution.Count == 0 && this.m_searchConditionsNotContainedInSolution.Count == 0)
    {
      flag3 = true;
    }
    else
    {
      if (this.m_searchConditionsContainedInSolution.Count == 0)
        flag1 = true;
      for (int index1 = 0; index1 < this.m_searchConditionsContainedInSolution.Count; ++index1)
      {
        flag1 = false;
        CApMFSearchCondition mfSearchCondition = this.m_searchConditionsContainedInSolution[index1] as CApMFSearchCondition;
        for (int index2 = 0; index2 < ((ArrayList) this.m_toolPrototypesInVariations[index]).Count && !flag1; ++index2)
        {
          int internalId = (int) ((ArrayList) this.m_toolPrototypesInVariations[index])[index2];
          flag1 = mfSearchCondition.DoesSatisfyCondition(internalId);
        }
        for (int index3 = 0; index3 < this.m_toolsWithoutVariations.Count && !flag1; ++index3)
        {
          int withoutVariation = (int) this.m_toolsWithoutVariations[index3];
          flag1 = mfSearchCondition.DoesSatisfyCondition(withoutVariation);
        }
        if (this.m_solutionContainsOperator == "OR" & flag1 || this.m_solutionContainsOperator == "AND" && !flag1)
          break;
      }
      if (this.m_searchConditionsNotContainedInSolution.Count == 0)
        flag2 = false;
      for (int index4 = 0; index4 < this.m_searchConditionsNotContainedInSolution.Count & flag1; ++index4)
      {
        flag2 = false;
        CApMFSearchCondition mfSearchCondition = this.m_searchConditionsNotContainedInSolution[index4] as CApMFSearchCondition;
        for (int index5 = 0; index5 < ((ArrayList) this.m_toolPrototypesInVariations[index]).Count && !flag2; ++index5)
        {
          int internalId = (int) ((ArrayList) this.m_toolPrototypesInVariations[index])[index5];
          flag2 = mfSearchCondition.DoesSatisfyCondition(internalId);
        }
        for (int index6 = 0; index6 < this.m_toolsWithoutVariations.Count && !flag2; ++index6)
        {
          int withoutVariation = (int) this.m_toolsWithoutVariations[index6];
          flag2 = mfSearchCondition.DoesSatisfyCondition(withoutVariation);
        }
        if (this.m_solutionDoesntContainOperator == "OR" && !flag2 || this.m_solutionDoesntContainOperator == "AND" & flag2)
          break;
      }
      flag3 = flag1 && !flag2;
    }
    return flag3;
  }

  private void GetDistanceForVariation(
    ref ArrayList raiserPath,
    ref ArrayList validSolutions,
    ref ArrayList invalidSolutions,
    ref CApMFFixtureDesignerSolution solution,
    ref ArrayList placementList,
    int variationIndex)
  {
    CApMFTransformation pointOnRaiser = this.m_fixtureUnitLocation.Multiply(this.m_placementOriginsWithoutVariations.Count <= 0 ? this.GetRelativeLocation(ref raiserPath) : this.GetRelativeLocation(ref this.m_placementOriginsWithoutVariations));
    TxTransformation closestPoint = (TxTransformation) null;
    double maxValue = double.MaxValue;
    int intermediateId = 0;
    ArrayList intermediatePath = new ArrayList();
    TxTransformation intermediatePlacementPoint = (TxTransformation) null;
    bool closestPlacementPoint = this.GetClosestPlacementPoint(ref pointOnRaiser, ref closestPoint, ref maxValue, ref intermediateId, ref intermediatePath, ref intermediatePlacementPoint, ref placementList);
    if (maxValue == double.MaxValue)
      return;
    EmpContext empContext;
    empContext.sessionId = this.m_sessionId;
    int num = (int) raiserPath[raiserPath.Count - 1];
    solution.Distance = Math.Round(maxValue, 2);
    solution.RaiserId = num;
    solution.PlacementPoint = closestPoint;
    if (intermediateId != 0)
    {
      solution.IntermediateId = intermediateId;
      solution.IntermediatePath = intermediatePath;
      solution.IntermediatePlacementPoint = intermediatePlacementPoint;
    }
    if (closestPlacementPoint)
    {
      validSolutions.Add((object) solution);
    }
    else
    {
      TxVector translationAsVector = pointOnRaiser.GetTranslationAsVector();
      TxVector translation = closestPoint.Translation;
      solution.Tolerance.Add((object) (translationAsVector.X - translation.X));
      solution.Tolerance.Add((object) (translationAsVector.Y - translation.Y));
      solution.Tolerance.Add((object) (translationAsVector.Z - translation.Z));
      invalidSolutions.Add((object) solution);
    }
  }

  private CApMFTransformation GetRelativeLocation(ref ArrayList path)
  {
    TxEmsGlobalServicesProvider servicesProvider = new TxEmsGlobalServicesProvider();
    CApMFTransformation relativeLocation = new CApMFTransformation();
    CApMFTransformation mfTransformation = new CApMFTransformation();
    foreach (int key in path)
    {
      CApMFTransformation m;
      if (this.m_instancesLocations.Contains((object) key))
      {
        m = this.m_instancesLocations[(object) key] as CApMFTransformation;
      }
      else
      {
        ITxPlanningObject field1 = (ITxPlanningObject) servicesProvider.GetObjectByInternalId(key).GetField("layout");
        ArrayList field2 = (ArrayList) field1.GetField("location");
        ArrayList field3 = (ArrayList) field1.GetField("rotation");
        m = new CApMFTransformation(Convert.ToDouble(field2[0]), Convert.ToDouble(field2[1]), Convert.ToDouble(field2[2]), Convert.ToDouble(field3[0]), Convert.ToDouble(field3[1]), Convert.ToDouble(field3[2]));
        this.m_instancesLocations.Add((object) key, (object) m);
      }
      relativeLocation = relativeLocation.Multiply(m);
    }
    if (this.m_resourcePlacementOrigin.Contains((object) (int) path[path.Count - 1]))
    {
      CApMFTransformation m = this.m_resourcePlacementOrigin[(object) (int) path[path.Count - 1]] as CApMFTransformation;
      relativeLocation = relativeLocation.Multiply(m);
    }
    return relativeLocation;
  }

  private bool GetClosestPlacementPoint(
    ref CApMFTransformation pointOnRaiser,
    ref TxTransformation closestPoint,
    ref double distance,
    ref int intermediateId,
    ref ArrayList intermediatePath,
    ref TxTransformation intermediatePlacementPoint,
    ref ArrayList placementList)
  {
    double currX1 = 0.0;
    double currY1 = 0.0;
    double currZ1 = 0.0;
    double num1 = double.MaxValue;
    double num2 = double.MaxValue;
    TxTransformation txTransformation1 = new TxTransformation();
    TxTransformation txTransformation2 = new TxTransformation();
    int num3 = 0;
    int num4 = 0;
    double rx1;
    double ry1;
    double rz1;
    pointOnRaiser.GetRotationRPY(out rx1, out ry1, out rz1);
    foreach (CApMFPlacementPoint mfPlacementPoint in placementList)
    {
      double num5 = double.MaxValue;
      CApMFTransformation refPoint1 = (CApMFTransformation) null;
      if (mfPlacementPoint.IntermediateUnitId != 0)
      {
        bool flag = false;
        if (!this.m_intermediateVariationsLocations.Contains((object) mfPlacementPoint.IntermediateUnitId))
        {
          this.m_intermediateVariationsLocations.Add((object) mfPlacementPoint.IntermediateUnitId, (object) new ArrayList());
          flag = true;
        }
        CApMFTransformation mfTransformation1 = (CApMFTransformation) null;
        double num6 = double.MaxValue;
        ArrayList arrayList1;
        if (this.m_intermediateVariations.Contains((object) mfPlacementPoint.IntermediateUnitId))
        {
          arrayList1 = (ArrayList) this.m_intermediateVariations[(object) mfPlacementPoint.IntermediateUnitId];
        }
        else
        {
          arrayList1 = this.GetIntermediateUnitVariations(mfPlacementPoint.IntermediateUnitId);
          this.m_intermediateVariations.Add((object) mfPlacementPoint.IntermediateUnitId, (object) arrayList1);
        }
        if (arrayList1.Count > 0)
        {
          for (int index1 = 0; index1 < arrayList1.Count; ++index1)
          {
            ArrayList arrayList2 = (ArrayList) arrayList1[index1];
            double currX2 = 0.0;
            double currY2 = 0.0;
            double currZ2 = 0.0;
            ArrayList path = arrayList2[0] as ArrayList;
            CApMFTransformation mfTransformation2;
            if (flag)
            {
              CApMFTransformation relativeLocation = this.GetRelativeLocation(ref path);
              ((ArrayList) this.m_intermediateVariationsLocations[(object) mfPlacementPoint.IntermediateUnitId]).Add((object) relativeLocation);
              mfTransformation2 = pointOnRaiser.Multiply(relativeLocation);
            }
            else
            {
              CApMFTransformation m = ((ArrayList) this.m_intermediateVariationsLocations[(object) mfPlacementPoint.IntermediateUnitId])[index1] as CApMFTransformation;
              mfTransformation2 = pointOnRaiser.Multiply(m);
            }
            CApMFTransformation m1 = arrayList2[1] as CApMFTransformation;
            CApMFTransformation refPoint2 = mfTransformation2.Multiply(m1);
            double rx2;
            double ry2;
            double rz2;
            refPoint2.GetRotationRPY(out rx2, out ry2, out rz2);
            if (!this.IsValidOrientation(mfPlacementPoint, rx2, ry2, rz2))
            {
              mfTransformation1 = (CApMFTransformation) null;
            }
            else
            {
              double distance1 = this.CalculateDistance(mfPlacementPoint, ref refPoint2, ref currX2, ref currY2, ref currZ2);
              if (num6 > distance1)
              {
                num6 = distance1;
                currX1 = currX2;
                currY1 = currY2;
                currZ1 = currZ2;
                refPoint1 = refPoint2;
                CApMFTransformation mfTransformation3 = m1.Inverse();
                intermediatePlacementPoint = new TxTransformation(mfTransformation3.GetTranslationAsVector(), mfTransformation3.GetRotationRPYAsVector(), (TxTransformation.TxRotationType) 1);
                intermediatePath.Clear();
                for (int index2 = 2; index2 < arrayList2.Count; ++index2)
                  intermediatePath.Add(arrayList2[index2]);
              }
            }
          }
          num5 = num6;
        }
        else
        {
          ArrayList fromConfiguration = CApMFFixtureDesignerUtils.GetIntermediatesFromConfiguration(mfPlacementPoint.IntermediateUnitId);
          if (fromConfiguration.Count > 0)
          {
            double currX3 = 0.0;
            double currY3 = 0.0;
            double currZ3 = 0.0;
            ArrayList path = fromConfiguration[0] as ArrayList;
            CApMFTransformation relativeLocation = this.GetRelativeLocation(ref path);
            CApMFTransformation mfTransformation4 = pointOnRaiser.Multiply(relativeLocation);
            CApMFTransformation intermediatePlacementPoint1 = CApMFFixtureDesignerUtils.GetIntermediatePlacementPoint((int) path[path.Count - 1]);
            CApMFTransformation refPoint3 = mfTransformation4.Multiply(intermediatePlacementPoint1.Inverse());
            double rx3;
            double ry3;
            double rz3;
            refPoint3.GetRotationRPY(out rx3, out ry3, out rz3);
            if (this.IsValidOrientation(mfPlacementPoint, rx3, ry3, rz3))
            {
              double distance2 = this.CalculateDistance(mfPlacementPoint, ref refPoint3, ref currX3, ref currY3, ref currZ3);
              currX1 = currX3;
              currY1 = currY3;
              currZ1 = currZ3;
              refPoint1 = refPoint3;
              intermediatePlacementPoint = new TxTransformation(intermediatePlacementPoint1.GetTranslationAsVector(), intermediatePlacementPoint1.GetRotationRPYAsVector(), (TxTransformation.TxRotationType) 1);
              intermediatePath.Clear();
              intermediatePath = (ArrayList) fromConfiguration.Clone();
              num5 = distance2;
            }
            else
              continue;
          }
        }
      }
      else if (this.IsValidOrientation(mfPlacementPoint, rx1, ry1, rz1))
      {
        refPoint1 = pointOnRaiser;
        num5 = this.CalculateDistance(mfPlacementPoint, ref refPoint1, ref currX1, ref currY1, ref currZ1);
      }
      else
        continue;
      if (num5 != double.MaxValue)
      {
        TxVector currPoint = new TxVector(currX1, currY1, currZ1);
        TxVector translationAsVector = refPoint1.GetTranslationAsVector();
        double rx4;
        double ry4;
        double rz4;
        this.m_fixtureUnitLocation.GetRotationRPY(out rx4, out ry4, out rz4);
        bool flag = this.IsValidOrientation(mfPlacementPoint, rx4, ry4, rz4);
        if (flag && this.IsPointWithinTolerance(this.m_fixtureUnitId, ref currPoint, ref translationAsVector) || !flag && this.IsPointWithinToleranceWhenNotSameOrientation(this.m_fixtureUnitId, ref currPoint, ref refPoint1))
        {
          if (num5 < num1)
          {
            num1 = num5;
            TxVector rotationRpyAsVector = refPoint1.GetRotationRPYAsVector();
            TxVector txVector = new TxVector(rotationRpyAsVector.X, rotationRpyAsVector.Y, rotationRpyAsVector.Z);
            txTransformation1.Translation = currPoint;
            txTransformation1.RotationRPY_XYZ = txVector;
            num3 = mfPlacementPoint.IntermediateUnitId;
          }
        }
        else if (num5 < num2)
        {
          num2 = num5;
          TxVector rotationRpyAsVector = refPoint1.GetRotationRPYAsVector();
          TxVector txVector = new TxVector(rotationRpyAsVector.X, rotationRpyAsVector.Y, rotationRpyAsVector.Z);
          txTransformation2.Translation = currPoint;
          txTransformation2.RotationRPY_XYZ = txVector;
          num4 = mfPlacementPoint.IntermediateUnitId;
        }
      }
    }
    bool closestPlacementPoint;
    if (num1 != double.MaxValue)
    {
      closestPlacementPoint = true;
      distance = num1;
      closestPoint = txTransformation1;
      intermediateId = num3;
    }
    else
    {
      closestPlacementPoint = false;
      distance = num2;
      closestPoint = txTransformation2;
      intermediateId = num4;
    }
    return closestPlacementPoint;
  }

  private double CalculateDistance(
    CApMFPlacementPoint placementPoint,
    ref CApMFTransformation refPoint,
    ref double currX,
    ref double currY,
    ref double currZ)
  {
    double maxValue = double.MaxValue;
    TxVector translationAsVector = refPoint.GetTranslationAsVector();
    if (!this.CalculateAllExactAxes(placementPoint, ref translationAsVector, ref maxValue, ref currX, ref currY, ref currZ) && !this.Calculate2FreeAxes(placementPoint, ref refPoint, ref maxValue, ref currX, ref currY, ref currZ) && !this.CalculateFreeAxis(placementPoint, ref translationAsVector, ref maxValue, ref currX, ref currY, ref currZ) && !this.CalculateStepAxis(placementPoint, ref translationAsVector, ref maxValue, ref currX, ref currY, ref currZ) && !this.Calculate2StepAxis(placementPoint, ref translationAsVector, ref maxValue, ref currX, ref currY, ref currZ))
      this.CalculateFreeAxisStepAxis(placementPoint, ref translationAsVector, ref maxValue, ref currX, ref currY, ref currZ);
    return maxValue;
  }

  private ArrayList GetIntermediateUnitVariations(int intermediateUnitId)
  {
    this.m_emsHandler.ImportDataToCache(intermediateUnitId);
    TxObjectList field = (TxObjectList) new TxEmsGlobalServicesProvider().GetObjectByInternalId(intermediateUnitId).GetField("children");
    ArrayList resourcePath = new ArrayList();
    ArrayList variations = new ArrayList();
    Hashtable variationHash = new Hashtable();
    foreach (ITxPlanningObject instancePlanningObj in (Collection<ITxObject>) field)
      this.CaluclateAllPossibleVariations(instancePlanningObj, ref variations, 0, resourcePath, false, variationHash);
    this.RemoveIntermediateVariationsWithNoFrame(ref variations);
    return variations;
  }

  private void AdjustPlacementPoints(ref ArrayList placementPoints)
  {
    TxVector translation = this.m_fixtureBaseLocation.Translation;
    TxVector rotationRpyXyz = this.m_fixtureBaseLocation.RotationRPY_XYZ;
    foreach (CApMFPlacementPoint mfPlacementPoint in placementPoints)
    {
      mfPlacementPoint.X.Value += translation.X;
      mfPlacementPoint.X.Min += translation.X;
      mfPlacementPoint.X.Max += translation.X;
      mfPlacementPoint.Y.Value += translation.Y;
      mfPlacementPoint.Y.Min += translation.Y;
      mfPlacementPoint.Y.Max += translation.Y;
      mfPlacementPoint.Z.Value += translation.Z;
      mfPlacementPoint.Z.Min += translation.Z;
      mfPlacementPoint.Z.Max += translation.Z;
      mfPlacementPoint.RX.Value += Math.Round(rotationRpyXyz.X / this.m_angularMultiplier, this.m_angularDigitsAfterThePoint);
      mfPlacementPoint.RX.Min += Math.Round(rotationRpyXyz.X / this.m_angularMultiplier, this.m_angularDigitsAfterThePoint);
      mfPlacementPoint.RX.Max += Math.Round(rotationRpyXyz.X / this.m_angularMultiplier, this.m_angularDigitsAfterThePoint);
      mfPlacementPoint.RY.Value += Math.Round(rotationRpyXyz.Y / this.m_angularMultiplier, this.m_angularDigitsAfterThePoint);
      mfPlacementPoint.RY.Min += Math.Round(rotationRpyXyz.Y / this.m_angularMultiplier, this.m_angularDigitsAfterThePoint);
      mfPlacementPoint.RY.Max += Math.Round(rotationRpyXyz.Y / this.m_angularMultiplier, this.m_angularDigitsAfterThePoint);
      mfPlacementPoint.RZ.Value += Math.Round(rotationRpyXyz.Z / this.m_angularMultiplier, this.m_angularDigitsAfterThePoint);
      mfPlacementPoint.RZ.Min += Math.Round(rotationRpyXyz.Z / this.m_angularMultiplier, this.m_angularDigitsAfterThePoint);
      mfPlacementPoint.RZ.Max += Math.Round(rotationRpyXyz.Z / this.m_angularMultiplier, this.m_angularDigitsAfterThePoint);
    }
  }

  private void CalculateFreeAxisStepAxis(
    CApMFPlacementPoint currPoint,
    ref TxVector refPoint,
    ref double currDistance,
    ref double currX,
    ref double currY,
    ref double currZ)
  {
    TxParameterizedPoint parameterizedPoint = (TxParameterizedPoint) null;
    TxLineData txLineData = (TxLineData) null;
    if (currPoint.X.Type == PointType.Free)
    {
      if (currPoint.Y.Type == PointType.Step)
      {
        for (double min = currPoint.Y.Min; min < currPoint.Y.Max; min += currPoint.Y.Step)
          txLineData = new TxLineData(new TxVector(currPoint.X.Min, min, currPoint.Z.Value), new TxVector(currPoint.X.Max, min, currPoint.Z.Value));
      }
      else if (currPoint.Z.Type == PointType.Step)
      {
        for (double min = currPoint.Z.Min; min < currPoint.Z.Max; min += currPoint.Z.Step)
          txLineData = new TxLineData(new TxVector(currPoint.X.Min, currPoint.Y.Value, min), new TxVector(currPoint.X.Max, currPoint.Y.Value, min));
      }
    }
    else if (currPoint.Y.Type == PointType.Free)
    {
      if (currPoint.X.Type == PointType.Step)
      {
        for (double min = currPoint.X.Min; min < currPoint.X.Max; min += currPoint.X.Step)
          txLineData = new TxLineData(new TxVector(min, currPoint.Y.Min, currPoint.Z.Value), new TxVector(min, currPoint.Y.Max, currPoint.Z.Value));
      }
      else if (currPoint.Z.Type == PointType.Step)
      {
        for (double min = currPoint.Z.Min; min < currPoint.Z.Max; min += currPoint.Z.Step)
          txLineData = new TxLineData(new TxVector(currPoint.X.Value, currPoint.Y.Min, min), new TxVector(currPoint.X.Value, currPoint.Y.Max, min));
      }
    }
    else if (currPoint.Z.Type == PointType.Free)
    {
      if (currPoint.X.Type == PointType.Step)
      {
        for (double min = currPoint.X.Min; min < currPoint.X.Max; min += currPoint.X.Step)
          txLineData = new TxLineData(new TxVector(min, currPoint.Y.Value, currPoint.Z.Min), new TxVector(min, currPoint.Y.Value, currPoint.Z.Max));
      }
      else if (currPoint.Y.Type == PointType.Step)
      {
        for (double min = currPoint.Y.Min; min < currPoint.Y.Max; min += currPoint.Y.Step)
          txLineData = new TxLineData(new TxVector(currPoint.X.Value, min, currPoint.Z.Min), new TxVector(currPoint.X.Value, min, currPoint.Z.Max));
      }
    }
    if (txLineData == null)
      return;
    txLineData.GetPointProjection(refPoint, ref currDistance, ref parameterizedPoint);
    TxVector point = parameterizedPoint.Point;
    currDistance = CApMFFixtureDesignerUtils.GetDistanceBetweenPoints(ref refPoint, ref point);
    currX = parameterizedPoint.Point.X;
    currY = parameterizedPoint.Point.Y;
    currZ = parameterizedPoint.Point.Z;
  }

  private bool Calculate2StepAxis(
    CApMFPlacementPoint currPoint,
    ref TxVector refPoint,
    ref double currDistance,
    ref double currX,
    ref double currY,
    ref double currZ)
  {
    bool flag = false;
    double num = double.MaxValue;
    if (currPoint.X.Type == PointType.Step && currPoint.Y.Type == PointType.Step && currPoint.Z.Type == PointType.Exact)
    {
      for (double min1 = currPoint.X.Min; min1 < currPoint.X.Max; min1 += currPoint.X.Step)
      {
        for (double min2 = currPoint.Y.Min; min2 < currPoint.Y.Max; min2 += currPoint.Y.Step)
        {
          TxVector point1 = new TxVector(min1, min2, currPoint.Z.Value);
          double distanceBetweenPoints = CApMFFixtureDesignerUtils.GetDistanceBetweenPoints(ref point1, ref refPoint);
          if (distanceBetweenPoints < num)
            num = distanceBetweenPoints;
        }
      }
      currDistance = num;
      flag = true;
    }
    if (currPoint.X.Type == PointType.Exact && currPoint.Y.Type == PointType.Step && currPoint.Z.Type == PointType.Step)
    {
      for (double min3 = currPoint.Y.Min; min3 < currPoint.Y.Max; min3 += currPoint.Y.Step)
      {
        for (double min4 = currPoint.Z.Min; min4 < currPoint.Z.Max; min4 += currPoint.Z.Step)
        {
          TxVector point1 = new TxVector(currPoint.X.Value, min3, min4);
          double distanceBetweenPoints = CApMFFixtureDesignerUtils.GetDistanceBetweenPoints(ref point1, ref refPoint);
          if (distanceBetweenPoints < num)
            num = distanceBetweenPoints;
        }
      }
      currDistance = num;
      flag = true;
    }
    if (currPoint.X.Type == PointType.Step && currPoint.Y.Type == PointType.Exact && currPoint.Z.Type == PointType.Step)
    {
      for (double min5 = currPoint.X.Min; min5 < currPoint.X.Max; min5 += currPoint.X.Step)
      {
        for (double min6 = currPoint.Z.Min; min6 < currPoint.Z.Max; min6 += currPoint.Z.Step)
        {
          TxVector point1 = new TxVector(min5, currPoint.Y.Value, min6);
          double distanceBetweenPoints = CApMFFixtureDesignerUtils.GetDistanceBetweenPoints(ref point1, ref refPoint);
          if (distanceBetweenPoints < num)
            num = distanceBetweenPoints;
        }
      }
      currDistance = num;
      flag = true;
    }
    return flag;
  }

  private bool CalculateStepAxis(
    CApMFPlacementPoint currPoint,
    ref TxVector refPoint,
    ref double currDistance,
    ref double currX,
    ref double currY,
    ref double currZ)
  {
    bool stepAxis = false;
    double num = double.MaxValue;
    if (currPoint.X.Type == PointType.Step && currPoint.Y.Type == PointType.Exact && currPoint.Z.Type == PointType.Exact)
    {
      TxVector point1 = new TxVector(0.0, currPoint.Y.Value, currPoint.Z.Value);
      for (double min = currPoint.X.Min; min < currPoint.X.Max; min += currPoint.X.Step)
      {
        point1.X = min;
        double distanceBetweenPoints = CApMFFixtureDesignerUtils.GetDistanceBetweenPoints(ref point1, ref refPoint);
        if (distanceBetweenPoints < num)
        {
          currX = min;
          num = distanceBetweenPoints;
        }
      }
      currDistance = num;
      currY = currPoint.Y.Value;
      currZ = currPoint.Z.Value;
      stepAxis = true;
    }
    if (currPoint.X.Type == PointType.Exact && currPoint.Y.Type == PointType.Step && currPoint.Z.Type == PointType.Exact)
    {
      TxVector point1 = new TxVector(currPoint.X.Value, 0.0, currPoint.Z.Value);
      for (double min = currPoint.Y.Min; min < currPoint.Y.Max; min += currPoint.Y.Step)
      {
        point1.Y = min;
        double distanceBetweenPoints = CApMFFixtureDesignerUtils.GetDistanceBetweenPoints(ref point1, ref refPoint);
        if (distanceBetweenPoints < num)
        {
          currY = min;
          num = distanceBetweenPoints;
        }
      }
      currDistance = num;
      currX = currPoint.X.Value;
      currZ = currPoint.Z.Value;
      stepAxis = true;
    }
    if (currPoint.X.Type == PointType.Exact && currPoint.Y.Type == PointType.Exact && currPoint.Z.Type == PointType.Step)
    {
      TxVector point1 = new TxVector(currPoint.X.Value, currPoint.Y.Value, 0.0);
      for (double min = currPoint.Z.Min; min < currPoint.Z.Max; min += currPoint.Z.Step)
      {
        point1.Z = min;
        double distanceBetweenPoints = CApMFFixtureDesignerUtils.GetDistanceBetweenPoints(ref point1, ref refPoint);
        if (distanceBetweenPoints < num)
        {
          currZ = min;
          num = distanceBetweenPoints;
        }
      }
      currDistance = num;
      currX = currPoint.X.Value;
      currY = currPoint.Y.Value;
      stepAxis = true;
    }
    return stepAxis;
  }

  private bool CalculateFreeAxis(
    CApMFPlacementPoint currPoint,
    ref TxVector refPoint,
    ref double currDistance,
    ref double currX,
    ref double currY,
    ref double currZ)
  {
    bool freeAxis = false;
    TxVector txVector1 = (TxVector) null;
    TxVector txVector2 = (TxVector) null;
    if (currPoint.X.Type == PointType.Free && currPoint.Y.Type == PointType.Exact && currPoint.Z.Type == PointType.Exact)
    {
      txVector1 = new TxVector(currPoint.X.Min, currPoint.Y.Value, currPoint.Z.Value);
      txVector2 = new TxVector(currPoint.X.Max, currPoint.Y.Value, currPoint.Z.Value);
    }
    else if (currPoint.X.Type == PointType.Exact && currPoint.Y.Type == PointType.Free && currPoint.Z.Type == PointType.Exact)
    {
      txVector1 = new TxVector(currPoint.X.Value, currPoint.Y.Min, currPoint.Z.Value);
      txVector2 = new TxVector(currPoint.X.Value, currPoint.Y.Max, currPoint.Z.Value);
    }
    else if (currPoint.X.Type == PointType.Exact && currPoint.Y.Type == PointType.Exact && currPoint.Z.Type == PointType.Free)
    {
      txVector1 = new TxVector(currPoint.X.Value, currPoint.Y.Value, currPoint.Z.Min);
      txVector2 = new TxVector(currPoint.X.Value, currPoint.Y.Value, currPoint.Z.Max);
    }
    if (TxVector.op_Inequality(txVector1, (TxVector) null) && TxVector.op_Inequality(txVector2, (TxVector) null))
    {
      TxParameterizedPoint parameterizedPoint;
      new TxLineData(txVector1, txVector2).GetPointProjection(refPoint, ref currDistance, ref parameterizedPoint);
      if (currPoint.X.Type == PointType.Free)
      {
        if (parameterizedPoint.Point.X < currPoint.X.Min)
          parameterizedPoint.Point.X = currPoint.X.Min;
        else if (parameterizedPoint.Point.X > currPoint.X.Max)
          parameterizedPoint.Point.X = currPoint.X.Max;
      }
      if (currPoint.Y.Type == PointType.Free)
      {
        if (parameterizedPoint.Point.Y < currPoint.Y.Min)
          parameterizedPoint.Point.Y = currPoint.Y.Min;
        else if (parameterizedPoint.Point.Y > currPoint.Y.Max)
          parameterizedPoint.Point.Y = currPoint.Y.Max;
      }
      if (currPoint.Z.Type == PointType.Free)
      {
        if (parameterizedPoint.Point.Z < currPoint.Z.Min)
          parameterizedPoint.Point.Z = currPoint.Z.Min;
        else if (parameterizedPoint.Point.Z > currPoint.Z.Max)
          parameterizedPoint.Point.Z = currPoint.Z.Max;
      }
      TxVector point = parameterizedPoint.Point;
      currDistance = CApMFFixtureDesignerUtils.GetDistanceBetweenPoints(ref refPoint, ref point);
      currX = parameterizedPoint.Point.X;
      currY = parameterizedPoint.Point.Y;
      currZ = parameterizedPoint.Point.Z;
      freeAxis = true;
    }
    return freeAxis;
  }

  private bool CalculateAllExactAxes(
    CApMFPlacementPoint currPoint,
    ref TxVector refPoint,
    ref double currDistance,
    ref double currX,
    ref double currY,
    ref double currZ)
  {
    bool allExactAxes = false;
    if (currPoint.X.Type == PointType.Exact && currPoint.Y.Type == PointType.Exact && currPoint.Z.Type == PointType.Exact)
    {
      TxVector point2 = new TxVector(currPoint.X.Value, currPoint.Y.Value, currPoint.Z.Value);
      currDistance = CApMFFixtureDesignerUtils.GetDistanceBetweenPoints(ref refPoint, ref point2);
      currX = currPoint.X.Value;
      currY = currPoint.Y.Value;
      currZ = currPoint.Z.Value;
      allExactAxes = true;
    }
    return allExactAxes;
  }

  private bool Calculate2FreeAxes(
    CApMFPlacementPoint currPoint,
    ref CApMFTransformation refPoint,
    ref double currDistance,
    ref double currX,
    ref double currY,
    ref double currZ)
  {
    bool flag = false;
    TxPlaneData plane = (TxPlaneData) null;
    if (this.GetPlaneFrom2FreeAxes(currPoint, ref plane))
    {
      double rx;
      double ry;
      double rz;
      this.m_fixtureUnitLocation.GetRotationRPY(out rx, out ry, out rz);
      if (this.IsValidOrientation(currPoint, rx, ry, rz))
      {
        TxVector translationAsVector = refPoint.GetTranslationAsVector();
        TxVector point1 = plane.ProjectPoint(translationAsVector);
        if (currPoint.X.Type == PointType.Free)
        {
          if (point1.X > currPoint.X.Max)
            point1.X = currPoint.X.Max;
          else if (point1.X < currPoint.X.Min)
            point1.X = currPoint.X.Min;
        }
        if (currPoint.Y.Type == PointType.Free)
        {
          if (point1.Y > currPoint.Y.Max)
            point1.Y = currPoint.Y.Max;
          else if (point1.Y < currPoint.Y.Min)
            point1.Y = currPoint.Y.Min;
        }
        if (currPoint.Z.Type == PointType.Free)
        {
          if (point1.Z > currPoint.Z.Max)
            point1.Z = currPoint.Z.Max;
          else if (point1.Z < currPoint.Z.Min)
            point1.Z = currPoint.Z.Min;
        }
        currDistance = CApMFFixtureDesignerUtils.GetDistanceBetweenPoints(ref point1, ref translationAsVector);
        currX = point1.X;
        currY = point1.Y;
        currZ = point1.Z;
        flag = true;
      }
      else
      {
        TxVector translationAsVector1 = refPoint.GetTranslationAsVector();
        CApMFTransformation m = this.m_fixtureUnitLocation.Inverse().Multiply(refPoint);
        TxVector translationAsVector2 = this.m_fixtureUnitLocation.Multiply(new CApMFTransformation(0.0, 0.0, this.m_maxToleranceZ, 0.0, 0.0, 0.0)).Multiply(m).GetTranslationAsVector();
        TxParameterizedPoint parameterizedPoint1;
        TxParameterizedPoint parameterizedPoint2;
        if (new TxLineData(translationAsVector1, translationAsVector2).GetIntersectionPoint(new TxLineData(plane.ProjectPoint(translationAsVector1), plane.ProjectPoint(translationAsVector2)), ref parameterizedPoint1, ref parameterizedPoint2))
        {
          TxVector point = parameterizedPoint1.Point;
          currDistance = CApMFFixtureDesignerUtils.GetDistanceBetweenPoints(ref point, ref translationAsVector1);
          currX = point.X;
          currY = point.Y;
          currZ = point.Z;
          flag = true;
        }
        else
        {
          TxVector translationAsVector3 = refPoint.GetTranslationAsVector();
          TxVector txVector = plane.ProjectPoint(translationAsVector3);
          if (Math.Abs(translationAsVector3.X - txVector.X) < 0.0001 && Math.Abs(translationAsVector3.Y - txVector.Y) < 0.0001 && Math.Abs(translationAsVector3.Z - txVector.Z) < 0.0001)
          {
            currDistance = 0.0;
            currX = txVector.X;
            currY = txVector.Y;
            currZ = txVector.Z;
            flag = true;
          }
        }
      }
    }
    return flag;
  }

  private bool IsPointWithinTolerance(
    int fixtureUnitId,
    ref TxVector currPoint,
    ref TxVector refPoint)
  {
    double num1 = refPoint.X - currPoint.X;
    double num2 = refPoint.Y - currPoint.Y;
    double num3 = refPoint.Z - currPoint.Z;
    return num1 >= this.m_minToleranceX && num1 <= this.m_maxToleranceX && num2 >= this.m_minToleranceY && num2 <= this.m_maxToleranceY && num3 >= this.m_minToleranceZ && num3 <= this.m_maxToleranceZ;
  }

  private bool IsPointWithinToleranceWhenNotSameOrientation(
    int fixtureUnitId,
    ref TxVector currPoint,
    ref CApMFTransformation refPoint)
  {
    CApMFTransformation mfTransformation = this.m_fixtureUnitLocation.Inverse().Multiply(refPoint);
    double rx;
    double ry;
    double rz;
    refPoint.GetRotationRPY(out rx, out ry, out rz);
    double x;
    double y;
    double z;
    new CApMFTransformation(currPoint.X, currPoint.Y, currPoint.Z, rx, ry, rz).Multiply(mfTransformation.Inverse()).Inverse().Multiply(this.m_fixtureUnitLocation).GetTranslation(out x, out y, out z);
    return x >= this.m_minToleranceX - 0.0001 && x <= this.m_maxToleranceX + 0.0001 && y >= this.m_minToleranceY - 0.0001 && y <= this.m_maxToleranceY + 0.0001 && z >= this.m_minToleranceZ - 0.0001 && z <= this.m_maxToleranceZ + 0.0001;
  }

  private bool IsValidOrientation(CApMFPlacementPoint currPoint, ref TxVector rotation)
  {
    double num1 = Math.Round(rotation.X / this.m_angularMultiplier, this.m_angularDigitsAfterThePoint);
    double num2 = Math.Round(rotation.Y / this.m_angularMultiplier, this.m_angularDigitsAfterThePoint);
    double num3 = Math.Round(rotation.Z / this.m_angularMultiplier, this.m_angularDigitsAfterThePoint);
    return (currPoint.RX.Type == PointType.Free || currPoint.RX.Type == PointType.Exact && currPoint.RX.Value == num1) & (currPoint.RY.Type == PointType.Free || currPoint.RY.Type == PointType.Exact && currPoint.RY.Value == num2) & (currPoint.RZ.Type == PointType.Free || currPoint.RZ.Type == PointType.Exact && currPoint.RZ.Value == num3);
  }

  private bool IsValidOrientation(CApMFPlacementPoint currPoint, double rx, double ry, double rz)
  {
    double num1 = Math.Round(rx / this.m_angularMultiplier, this.m_angularDigitsAfterThePoint);
    double num2 = Math.Round(ry / this.m_angularMultiplier, this.m_angularDigitsAfterThePoint);
    double num3 = Math.Round(rz / this.m_angularMultiplier, this.m_angularDigitsAfterThePoint);
    return (currPoint.RX.Type == PointType.Free || currPoint.RX.Type == PointType.Exact && currPoint.RX.Value == num1) & (currPoint.RY.Type == PointType.Free || currPoint.RY.Type == PointType.Exact && currPoint.RY.Value == num2) & (currPoint.RZ.Type == PointType.Free || currPoint.RZ.Type == PointType.Exact && currPoint.RZ.Value == num3);
  }

  private bool GetPlaneFrom2FreeAxes(CApMFPlacementPoint currPoint, ref TxPlaneData plane)
  {
    bool planeFrom2FreeAxes = false;
    if (currPoint.X.Type == PointType.Free && currPoint.Y.Type == PointType.Free)
    {
      TxVector txVector1 = new TxVector(currPoint.X.Min, currPoint.Y.Min, currPoint.Z.Value);
      TxVector txVector2 = new TxVector(currPoint.X.Max, currPoint.Y.Min, currPoint.Z.Value);
      TxVector txVector3 = new TxVector(currPoint.X.Max, currPoint.Y.Max, currPoint.Z.Value);
      plane = new TxPlaneData(txVector1, txVector2, txVector3);
      planeFrom2FreeAxes = true;
    }
    else if (currPoint.X.Type == PointType.Free && currPoint.Z.Type == PointType.Free)
    {
      TxVector txVector4 = new TxVector(currPoint.X.Min, currPoint.Z.Min, currPoint.Z.Value);
      TxVector txVector5 = new TxVector(currPoint.X.Max, currPoint.Z.Min, currPoint.Z.Value);
      TxVector txVector6 = new TxVector(currPoint.X.Max, currPoint.Z.Max, currPoint.Z.Value);
      plane = new TxPlaneData(txVector4, txVector5, txVector6);
      planeFrom2FreeAxes = true;
    }
    else if (currPoint.Y.Type == PointType.Free && currPoint.Z.Type == PointType.Free)
    {
      TxVector txVector7 = new TxVector(currPoint.Y.Min, currPoint.Z.Min, currPoint.Z.Value);
      TxVector txVector8 = new TxVector(currPoint.Y.Max, currPoint.Z.Min, currPoint.Z.Value);
      TxVector txVector9 = new TxVector(currPoint.Y.Max, currPoint.Z.Max, currPoint.Z.Value);
      plane = new TxPlaneData(txVector7, txVector8, txVector9);
      planeFrom2FreeAxes = true;
    }
    return planeFrom2FreeAxes;
  }

  private int GetInternalIdFromPlanningObj(TxPlanningObject planningObj)
  {
    TxPlanningObjectEx.SetEmsServicesProviderCacheFlags(planningObj, (TxEmsServicesProviderCacheFlagsEx) 2);
    int internalId = (planningObj.PlatformServicesProvider as TxEmsServicesProvider).InternalId;
    if (!this.m_internalIdsPlanningObjects.Contains((object) internalId))
      this.m_internalIdsPlanningObjects.Add((object) internalId, (object) planningObj);
    return internalId;
  }

  private void HandleVariationPrototype(
    int varParentId,
    ref ArrayList variations,
    ref Hashtable variationHash,
    ref TxObjectList varChildren,
    bool isRaiser)
  {
    int count = variations.Count;
    if (varParentId != 0)
    {
      foreach (int index1 in (ArrayList) ((ArrayList) variationHash[(object) varParentId]).Clone())
      {
        ArrayList arrayList1 = (ArrayList) ((ArrayList) variations[index1]).Clone();
        bool flag = false;
        foreach (TxPlanningObject planningObj in (Collection<ITxObject>) varChildren)
        {
          int idFromPlanningObj = this.GetInternalIdFromPlanningObj(planningObj);
          if (((ArrayList) variations[index1]).Contains((object) idFromPlanningObj))
          {
            flag = true;
            break;
          }
        }
        if (!flag)
        {
          int idFromPlanningObj1 = this.GetInternalIdFromPlanningObj((TxPlanningObject) ((Collection<ITxObject>) varChildren)[0]);
          ((ArrayList) variations[index1]).Add((object) idFromPlanningObj1);
          this.AddVariationToHash(ref variationHash, idFromPlanningObj1, index1);
          for (int index2 = 1; index2 < ((Collection<ITxObject>) varChildren).Count; ++index2)
          {
            ArrayList arrayList2 = (ArrayList) arrayList1.Clone();
            int idFromPlanningObj2 = this.GetInternalIdFromPlanningObj((TxPlanningObject) ((Collection<ITxObject>) varChildren)[index2]);
            arrayList2.Add((object) idFromPlanningObj2);
            variations.Add((object) arrayList2);
            if (isRaiser)
              this.m_toolPrototypesInVariations.Add((object) (ArrayList) ((ArrayList) this.m_toolPrototypesInVariations[index1]).Clone());
            int num = 0;
            if (arrayList2[0] is ArrayList)
              ++num;
            for (int index3 = num; index3 < arrayList2.Count; ++index3)
            {
              int id = (int) arrayList2[index3];
              this.AddVariationToHash(ref variationHash, id, variations.Count - 1);
            }
          }
        }
      }
    }
    else if (count == 0)
    {
      foreach (ITxPlanningObject planningObj in (Collection<ITxObject>) varChildren)
      {
        ArrayList arrayList = new ArrayList();
        int idFromPlanningObj = this.GetInternalIdFromPlanningObj((TxPlanningObject) planningObj);
        arrayList.Add((object) idFromPlanningObj);
        variations.Add((object) arrayList);
        if (isRaiser)
          this.m_toolPrototypesInVariations.Add((object) new ArrayList());
        this.AddVariationToHash(ref variationHash, idFromPlanningObj, variations.Count - 1);
      }
    }
    else
    {
      for (int index4 = 0; index4 < count; ++index4)
      {
        ArrayList arrayList3 = (ArrayList) ((ArrayList) variations[index4]).Clone();
        int idFromPlanningObj3 = this.GetInternalIdFromPlanningObj((TxPlanningObject) ((Collection<ITxObject>) varChildren)[0]);
        ((ArrayList) variations[index4]).Add((object) idFromPlanningObj3);
        this.AddVariationToHash(ref variationHash, idFromPlanningObj3, index4);
        for (int index5 = 1; index5 < ((Collection<ITxObject>) varChildren).Count; ++index5)
        {
          ArrayList arrayList4 = (ArrayList) arrayList3.Clone();
          int idFromPlanningObj4 = this.GetInternalIdFromPlanningObj((TxPlanningObject) ((Collection<ITxObject>) varChildren)[index5]);
          arrayList4.Add((object) idFromPlanningObj4);
          variations.Add((object) arrayList4);
          if (isRaiser)
            this.m_toolPrototypesInVariations.Add((object) (ArrayList) ((ArrayList) this.m_toolPrototypesInVariations[index4]).Clone());
          int num = 0;
          if (arrayList4[0] is ArrayList)
            ++num;
          for (int index6 = num; index6 < arrayList4.Count; ++index6)
          {
            int id = (int) arrayList4[index6];
            this.AddVariationToHash(ref variationHash, id, variations.Count - 1);
          }
        }
      }
    }
  }

  private void AddVariationToHash(ref Hashtable varHash, int id, int index)
  {
    if (!varHash.Contains((object) id))
      varHash.Add((object) id, (object) new ArrayList()
      {
        (object) index
      });
    else
      ((ArrayList) varHash[(object) id]).Add((object) index);
  }

  private bool CheckIfRaiserOrIntermediate(
    bool isRaiser,
    ITxPlanningObject instanceObj,
    int instanceId,
    ITxPlanningObject prototypeObj)
  {
    bool flag = false;
    if (isRaiser)
    {
      if (this.m_raiserInternalIds.Contains((object) instanceId))
        flag = (bool) this.m_raiserInternalIds[(object) instanceId];
      else if (Convert.ToInt32(prototypeObj.GetField("Modfix_ConnectingPart")) == 1)
      {
        flag = true;
        this.m_raiserInternalIds.Add((object) instanceId, (object) true);
      }
      else
        this.m_raiserInternalIds.Add((object) instanceId, (object) false);
    }
    else if (instanceObj.GetField("IntermediateUnitPlacementPoint") != null)
      flag = true;
    return flag;
  }

  private void CreateFixtureDescendatns(
    int instanceId,
    ITxCompoundResourceCreation targetCompRes,
    ref CApMFFixtureDesignerSolution solution,
    TxTransformation currentLocation)
  {
    ITxPlanningObject objectByInternalId = (TxApplication.ActiveDocument.PlatformGlobalServicesProvider as TxEmsGlobalServicesProvider).GetObjectByInternalId(instanceId);
    EmpContext empContext;
    empContext.sessionId = this.m_sessionId;
    EmpToolPrototypeClass toolPrototypeClass = new EmpToolPrototypeClass();
    EmpToolInstanceClass toolInstanceClass = new EmpToolInstanceClass();
    ITxPlanningObject field1 = (ITxPlanningObject) objectByInternalId.GetField("prototype");
    EmpObjectKey empObjectKey1;
    empObjectKey1.objectId = ((TxEmsServicesProvider) field1.PlatformServicesProvider).InternalId;
    ITxPlanningObject field2 = (ITxPlanningObject) objectByInternalId.GetField("layout");
    ArrayList field3 = (ArrayList) field2.GetField("location");
    ArrayList field4 = (ArrayList) field2.GetField("rotation");
    TxTransformation txTransformation1 = new TxTransformation(new TxVector(Convert.ToDouble(field3[0]), Convert.ToDouble(field3[1]), Convert.ToDouble(field3[2])), new TxVector(Convert.ToDouble(field4[0]), Convert.ToDouble(field4[1]), Convert.ToDouble(field4[2])), (TxTransformation.TxRotationType) 1);
    TxTransformation currentLocation1 = TxTransformation.op_Multiply(currentLocation, txTransformation1);
    if (field1.IsDerivedFromPlanningType("UnitConfigurationPrototype"))
    {
      TxCompoundResourceCreationData resourceCreationData = new TxCompoundResourceCreationData(TxObjectEx.GetPlanningObjectName((ITxObject) objectByInternalId), currentLocation1);
      TxCompoundResource compoundResource = targetCompRes.CreateCompoundResource(resourceCreationData);
      foreach (ITxPlanningObject itxPlanningObject in (Collection<ITxObject>) field1.GetField("children"))
        this.CreateFixtureDescendatns((itxPlanningObject.PlatformServicesProvider as TxEmsServicesProvider).InternalId, (ITxCompoundResourceCreation) compoundResource, ref solution, currentLocation1);
    }
    else if (field1.IsDerivedFromPlanningType("UnitConfigurationVarPrototype"))
    {
      int num = 0;
      TxObjectList field5 = (TxObjectList) field1.GetField("children");
      ITxPlanningObject itxPlanningObject1 = (ITxPlanningObject) null;
      foreach (ITxPlanningObject itxPlanningObject2 in (Collection<ITxObject>) field5)
      {
        TxEmsServicesProvider servicesProvider = itxPlanningObject2.PlatformServicesProvider as TxEmsServicesProvider;
        if (solution.VariationPath.Contains((object) servicesProvider.InternalId))
        {
          num = servicesProvider.InternalId;
          itxPlanningObject1 = itxPlanningObject2;
          break;
        }
      }
      EmpObjectKey empObjectKey2;
      empObjectKey2.objectId = num;
      string str = toolInstanceClass[ref empContext, ref empObjectKey2];
      if (num == 0)
        return;
      foreach (ITxPlanningObject itxPlanningObject3 in (Collection<ITxObject>) ((ITxPlanningObject) itxPlanningObject1.GetField("prototype")).GetField("children"))
        this.CreateFixtureDescendatns((itxPlanningObject3.PlatformServicesProvider as TxEmsServicesProvider).InternalId, targetCompRes, ref solution, currentLocation1);
    }
    else
    {
      if (!field1.IsDerivedFromPlanningType("ToolPrototype"))
        return;
      EmpObjectKey threeDrep = toolPrototypeClass.GetThreeDRep(ref empContext, ref empObjectKey1);
      string str1 = new EmpThreeDRepClass()[ref empContext, ref threeDrep];
      ITxComponent itxComponent = TxApplication.ActiveDocument.PhysicalRoot.InsertComponent(new TxInsertComponentCreationData(TxObjectEx.GetPlanningObjectName((ITxObject) objectByInternalId), str1)
      {
        Prototype = field1
      });
      ITxObjectCollection objectCollection = targetCompRes as ITxObjectCollection;
      if (objectCollection.CanBeAdded((ITxObject) itxComponent))
        objectCollection.AddObject((ITxObject) itxComponent);
      (itxComponent as ITxLocatableObject).AbsoluteLocation = currentLocation1;
      bool flag = false;
      if (solution.RaiserId != 0)
      {
        flag = this.GetInternalIdFromPlanningObj(this.m_instancesPrototypes[(object) solution.RaiserId] as ITxPlanningObject as TxPlanningObject) == empObjectKey1.objectId;
        if (flag)
          solution.RaiserLocation = currentLocation1;
      }
      if (!(solution.IntermediateId != 0 & flag))
        return;
      ITxLocatableObject itxLocatableObject = itxComponent as ITxLocatableObject;
      TxTransformation txTransformation2 = currentLocation1;
      if (this.m_resourcePlacementOrigin.Contains((object) solution.RaiserId))
      {
        CApMFTransformation mfTransformation = this.m_resourcePlacementOrigin[(object) solution.RaiserId] as CApMFTransformation;
        TxTransformation txTransformation3 = new TxTransformation(mfTransformation.GetTranslationAsVector(), mfTransformation.GetRotationRPYAsVector(), (TxTransformation.TxRotationType) 1);
        txTransformation2 = TxTransformation.op_Multiply(txTransformation2, txTransformation3);
      }
      TxTransformation currentLocation2 = TxTransformation.op_Multiply(txTransformation2, solution.IntermediatePlacementPoint.Inverse);
      solution.IntermediateLocation = currentLocation2;
      CApMFFixtureDesignerSolution solution1 = new CApMFFixtureDesignerSolution();
      solution1.VariationPath = solution.IntermediatePath;
      EmpObjectKey empObjectKey3;
      empObjectKey3.objectId = solution.IntermediateId;
      string str2 = toolInstanceClass[ref empContext, ref empObjectKey3];
      foreach (EmpObjectKey child in toolPrototypeClass.GetChildren(ref empContext, ref empObjectKey3))
        this.CreateFixtureDescendatns(child.objectId, targetCompRes, ref solution1, currentLocation2);
    }
  }

  private TxObjectList GetObjectListFromHash(
    int internalId,
    string fieldName,
    ref Hashtable hash,
    ITxPlanningObject planningObj)
  {
    TxObjectList field;
    if (hash.Contains((object) internalId))
    {
      field = hash[(object) internalId] as TxObjectList;
    }
    else
    {
      field = (TxObjectList) planningObj.GetField(fieldName);
      hash.Add((object) internalId, (object) field);
    }
    return field;
  }

  private ITxPlanningObject GetPlanningObjectFromHash(
    int internalId,
    string fieldName,
    ref Hashtable hash,
    ITxPlanningObject planningObj)
  {
    ITxPlanningObject field;
    if (hash.Contains((object) internalId))
    {
      field = hash[(object) internalId] as ITxPlanningObject;
    }
    else
    {
      field = (ITxPlanningObject) planningObj.GetField(fieldName);
      hash.Add((object) internalId, (object) field);
    }
    return field;
  }

  internal bool ShouldCollectPlacementOrigins
  {
    get => this.m_shouldCollectPlacementOrigins;
    set => this.m_shouldCollectPlacementOrigins = value;
  }

  internal string SolutionContainsOperator => this.m_solutionContainsOperator;

  internal string SolutionDoesntContainOperator => this.m_solutionDoesntContainOperator;

  private enum ClassType
  {
    CONFIGURATION,
    VARIATION,
    TOOL_PROTOTYPE,
  }
}
